

 

 var NDIGITS = 16;

 var STACKSIZE = 12;

 

 var value = 0;         // current value in display

 var memory = GetCookie("CalcMemory");  // current value in memory

 if (!memory) memory = 0;

 var level = 0;         // no. of items on stack

 var entered = true;    // has value on display been 'entered'?

 var decimal = 0;               // multiplier when entering after decimal point

 var fixed = 0;         // force trailing zero display when entering decimals

 var exponent = false;  // currently entering exponent?

 var inverse = false;   // has the INV key been pressed?

 

 if (location.search)

 {

        // pass in value through command line

        value = location.search.substring(1,location.search.length);

 }

 

 function stackItem()

 {

        this.value = 0;

        this.op = "";

 }

 

 function array(length)

 {

        this[0] = 0;

        for (i=0; i<length; ++i)

        {

                this[i] = 0;

                this[i] = new stackItem();

        }

        this.length = length;

 }

 

 stack = new array(STACKSIZE);

 

 function push(value,op,prec)

 {

        if (level==STACKSIZE)

                return false;

        for (i=level;i>0; --i)

        {

                stack[i].value = stack[i-1].value;

                stack[i].op = stack[i-1].op;

                stack[i].prec = stack[i-1].prec;

        }

        stack[0].value = value;

        stack[0].op = op;

        stack[0].prec = prec;

        ++level;

        return true;

}



function pop()

{

        if (level==0)

                return false;

        for (i=0;i<level; ++i)

        {

                stack[i].value = stack[i+1].value;

                stack[i].op = stack[i+1].op;

                stack[i].prec = stack[i+1].prec;

        }

        --level;

        return true;

 }

 

 function format(value)

 {

        var valStr = "" + value;

        if (valStr.indexOf("N")>=0 || (value == 2*value && value == 1+value))

                return "Error ";

        var i = valStr.indexOf("e")

        if (i>=0)

        {

                var expStr = valStr.substring(i+1,valStr.length);

                if (i>11) i=11;  // max 11 digits

                valStr = valStr.substring(0,i);

                if (valStr.indexOf(".")<0) valStr += ".";

                valStr += " " + expStr;

        }

        else

        {

                var valNeg = false;

                if (value < 0)

                        { value = -value; valNeg = true; }


                var valInt = Math.floor(value);

                var valFrac = value - valInt;

                var prec = NDIGITS - (""+valInt).length - 1;    // how many digits available after period

                if (! entered && fixed>0)

                        prec = fixed;

                var mult = " 1000000000000000000".substring(1,prec+2);

                var frac = Math.floor(valFrac * mult + 0.5);


                valInt = Math.floor(Math.floor(value * mult + .5) / mult);


                if (valNeg)


                        valStr = "-" + valInt;


                else


                        valStr = "" + valInt;


                var fracStr = "00000000000000"+frac;

                fracStr = fracStr.substring(fracStr.length-prec, fracStr.length);

                i = fracStr.length-1;

                if (entered || fixed==0)

                {

                        // remove trailing zeros unless fixed during entry.

                        while (i>=0 && fracStr.charAt(i)=="0")

                                --i;

                        fracStr = fracStr.substring(0,i+1);

                }

                if (i>=0) valStr += "." + fracStr;

//              document.result.debugField.value = "prec "+prec+", mult "+mult+", frac "+frac;

        }

        return valStr;

}



function refresh()

{

        var display = format(value);

        if (exponent)

        {

                if (expval<0)

                        display += " " + expval;

                else

                        display += " +" + expval;

        }

        if (display.indexOf(".")<0 && display != "Error ")

        {

                if (entered || decimal>0)

                        display += '.';

                else

                        display += ' ';

        }

        display = "               " + display;

        display = display.substring(display.length-NDIGITS-1,display.length);

        document.result.result.value = display;

        inverse = false;

}



function clearAll()

{

        level = 0;

        clear();

}



function clear()

{

        exponent = false;

        value = 0;

        enter();

        refresh();

}



function evalx()

{

        if (level==0)

                return false;

        op = stack[0].op;

        sval = stack[0].value;

//      alert("eval "+sval+op+value);

        if (op == "+")

                value = sval + value;

        else if (op == '-')

                value = sval - value;

        else if (op == '*')

                value = sval * value;

        else if (op == '/')

                value = sval / value;

        else if (op == 'pow')

                value = Math.pow(sval,value);

        pop();

        if (op=='(')

                return false;

        return true;

}


function openp()

{

        enter();

        if (!push(0,'(',0))

        {

                value = "NAN";

        }

        refresh();

}



function closep()

{

        enter();

        while (evalx())

                ;

        refresh();

}

function operator(op)

{

        enter();

        if (op=='+' || op=='-')

                prec = 1;

        else if (op=='*' || op=='/')

                prec = 2;

        else if (op=="pow")

                prec = 3;

        if (level>0 && prec <= stack[0].prec)

                evalx();

        if (!push(value,op,prec))

        {

                value = "NAN";

        }

        refresh();

 }

 

 function enter()

 {

        if (exponent)

                value = value * Math.exp(expval * Math.LN10);

        entered = true;

        exponent = false;

        decimal = 0;

        fixed = 0;

 }

 

 function equals()

 {

        enter()

        while (level>0)

                evalx();

        refresh();

}



function digit(n)

{

        if (entered)

        {

                value = 0;

                digits = 0;

                entered = false;


        }


        if (n==0 && digits==0)


        {


                refresh();


                return;


        }


        if (exponent)

        {

                if (expval<0)

                        n = -n;

                if (digits < 3)

                {

                        expval = expval * 10 + n;

                        ++digits;

                        refresh();

                }

                return;

        }

        if (value<0)

                n = -n;

        if (digits < NDIGITS-1)

        {

                ++digits;

                if (decimal>0)

                {

                        decimal = decimal * 10;

                        value = value + (n/decimal);

                        ++fixed;

                }

                else

                        value = value * 10 + n;

        }

        refresh();

}



function sign()

{

        if (exponent)

                expval = -expval;

        else

                value = -value;

        refresh();

}



function period()

{

        if (entered)

        {

                value = 0;

                digits = 1;

        }

        entered = false;

        if (decimal == 0)

        {

                decimal = 1;

        }

        refresh();

}



function exp()

{

        if (entered || exponent)

                return;

        exponent = true;

        expval = 0;

        digits = 0;

        decimal = 0;

        refresh();

}



function inv()

{

        inverse = !inverse;

}



function func(f)

{

        enter();

        if (f=="1/x")

                value = 1/value;

        else if (f=="swap")

        {

                var tmp = value;

                value = stack[0].value;

                stack[0].value = tmp;

        }

        else if (f=='n!')

        {

                if (value<0 || value>200 || value != Math.round(value))

                        value = "NAN";

                else

                {

                        var n = 1;

                        var i;

                        for (i=1;i<=value;++i)

                                n *= i;

                        value = n;

                }

        }

        else if (f=="MR")

                value = memory;

        else if (f=="M+")

        {

                memory += value;

                SetCookie("CalcMemory", memory);

        }

        else if (f=="Min")

        {

                memory = value;

                SetCookie("CalcMemory", memory);

        }

        else if (inverse)

        {

                if (f=="sin")

                        value = Math.asin(value)*180/Math.PI;

                else if (f=="cos")

                        value = Math.acos(value)*180/Math.PI;

                else if (f=="tan")

                        value = Math.atan(value)*180/Math.PI;

                else if (f=="log")

                        value = Math.exp(value * Math.LN10);

                else if (f=="log2")

                        value = Math.exp(value * Math.LN2);

                else if (f=="ln")

                        value = Math.exp(value);

                else if (f=="sqrt")

                        value = value*value;

                else if (f=="pi")

                        value = Math.E;

        }

        else

        {

                if (f=="sin")

                        value = Math.sin(value/180 * Math.PI);

                else if (f=="cos")

                        value = Math.cos(value/180 * Math.PI);

                else if (f=="tan")

                        value = Math.tan(value/180 * Math.PI);

                else if (f=="log")

                        value = Math.log(value)/Math.LN10;

                else if (f=="log2")

                        value = Math.log(value)/Math.LN2;

                else if (f=="ln")

                        value = Math.log(value);

                else if (f=="sqrt")

                        value = Math.sqrt(value);

                else if (f=="pi")

                        value = Math.PI;

        }

        refresh();

 }

 

 function hex()

 {

        location = "js-hcalc.htm?"+value;

 }


function getCookieVal (offset) {

  var endstr = document.cookie.indexOf (";", offset);

  if (endstr == -1)

    endstr = document.cookie.length;

  return unescape(document.cookie.substring(offset, endstr));

}


function GetCookie (name) {

  var arg = name + "=";

  var alen = arg.length;

  var clen = document.cookie.length;

  var i = 0;

  while (i < clen) {

     var j = i + alen;

     if (document.cookie.substring(i, j) == arg)

       return getCookieVal (j);

     i = document.cookie.indexOf(" ", i) + 1;

     if (i == 0) break; 

   }

   return null;

 }

 function SetCookie (name, value) {

   var argv = SetCookie.arguments;

   var argc = SetCookie.arguments.length;

   var expires = (argc > 2) ? argv[2] : null;

  var path = (argc > 3) ? argv[3] : null;

  var domain = (argc > 4) ? argv[4] : null;

  var secure = (argc > 5) ? argv[5] : false;

  document.cookie = name + "=" + escape (value) +

    ((expires == null) ? "" : ("; expires=" + expires.toGMTString())) +

    ((path == null) ? "" : ("; path=" + path)) +

    ((domain == null) ? "" : ("; domain=" + domain)) +

    ((secure == true) ? "; secure" : "");

}

function DeleteCookie (name) {

  var exp = new Date();

  exp.setTime (exp.getTime() - 1);  // This cookie is history

  var cval = GetCookie (name);

  document.cookie = name + "=" + cval + "; expires=" + exp.toGMTString();

}


